home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’97 / MonitorDoubler / source code / MonitorDoublerExtension.cp < prev    next >
Encoding:
Text File  |  1997-06-28  |  3.8 KB  |  162 lines  |  [TEXT/CWIE]

  1. #ifndef __TRAPS__
  2. #    include <Traps.h>
  3. #endif
  4.  
  5. #ifndef __RESOURCES__
  6. #    include <Resources.h>
  7. #endif
  8.  
  9. #ifndef __A4STUFF__
  10. #    include <A4Stuff.h>
  11. #endif
  12.  
  13. #ifndef __DISPLAYS__
  14. #    include <Displays.h>
  15. #endif
  16.  
  17. enum { kBottomPixels = 25 };
  18.  
  19. typedef pascal void (*vInitGDevice)
  20.     (short qdRefNum, long mode, GDHandle gdh);
  21.  
  22. static GDHandle            gStripDevice;
  23. static vInitGDevice        gInitGDevice;
  24.  
  25. extern pascal OSErr CallOldDMMoveDisplay
  26.     (GDHandle moveDevice, short x, short y, Handle displayState, UniversalProcPtr)
  27.         = {0x303C, 0x0609, 0x2F17, 0x41FA, 0x0008, 0x2F48, 0x0004, 0x4E75};
  28.  
  29. static UInt16 GetRowBytes (UInt16 rowBytes)
  30. {
  31.     return 0x7FFF & rowBytes;
  32. }
  33.  
  34. static UInt16 GetRowBytes (PixMapHandle pmh)
  35. {
  36.     return GetRowBytes ((**pmh).rowBytes);
  37. }
  38.  
  39. static UInt16 GetRowBytes (GDHandle gdh)
  40. {
  41.     return GetRowBytes ((**gdh).gdPMap);
  42. }
  43.  
  44. static pascal void AdjustStripDevice (void)
  45. {
  46.     GDHandle        mainDevice                = ::GetMainDevice ( );
  47.     PixMapHandle    mainDevicePixMap        = (**mainDevice).gdPMap,
  48.                     stripDevicePixMap        = (**gStripDevice).gdPMap;
  49.  
  50.     (**mainDevice).gdRect.bottom        -= kBottomPixels;
  51.     (**mainDevicePixMap).bounds.bottom    -= kBottomPixels;
  52.  
  53.     (**gStripDevice).gdRect.top = (**mainDevice).gdRect.bottom;
  54.     (**stripDevicePixMap).bounds.top = (**mainDevicePixMap).bounds.bottom;
  55.  
  56.     UInt32 stripDeviceHeight =
  57.         (**mainDevice).gdRect.bottom - (**mainDevice).gdRect.top;
  58.     UInt32 baseAddrOffset =
  59.         stripDeviceHeight * GetRowBytes (mainDevicePixMap);
  60.  
  61.     (**stripDevicePixMap).baseAddr += baseAddrOffset;
  62.  
  63.     (**gStripDevice).gdFlags = (**mainDevice).gdFlags;
  64.     SetDeviceAttribute (gStripDevice,ramInit,false);
  65.     SetDeviceAttribute (gStripDevice,mainScreen,false);
  66. }
  67.  
  68. static pascal void InitGDevicePatch (short qdRefNum, long mode, GDHandle gdh)
  69. {
  70.     long preservedA4 = SetCurrentA4 ( );
  71.  
  72.     GDHandle mainDevice = ::GetMainDevice ( );
  73.  
  74.     if (gdh == gStripDevice)
  75.         gdh = mainDevice;
  76.  
  77.     gInitGDevice (qdRefNum,mode,gdh);
  78.  
  79.     if (gdh == mainDevice)
  80.     {
  81.         gInitGDevice ((**mainDevice).gdRefNum, (**mainDevice).gdMode, gStripDevice);
  82.         AdjustStripDevice ( );
  83.     }
  84.  
  85.     SetA4 (preservedA4);
  86. }
  87.  
  88. static pascal OSErr MoveDisplayPatch
  89.     (GDHandle moveDevice, short x, short y, Handle displayState, UniversalProcPtr old)
  90. {
  91.     long preservedA4 = SetCurrentA4 ( );
  92.  
  93.     OSErr err = noErr;
  94.  
  95.     if (gStripDevice != moveDevice)
  96.         err = CallOldDMMoveDisplay (moveDevice,x,y,displayState,old);
  97.  
  98.     SetA4 (preservedA4);
  99.  
  100.     return err;
  101. }
  102.  
  103. static pascal asm UniversalProcPtr DisplayDispatchPatchAsm (UniversalProcPtr)
  104. {
  105.         MOVE.L        (SP)+,A1
  106.         LEA            @hack1+2,A0
  107.         MOVE.L        (SP),(A0)
  108.         LEA            @hack2+2,A0
  109.         MOVE.L        (SP)+,(A0)
  110.         LEA            @patch,A0
  111.         MOVE.L        A0,(SP)
  112.         JMP            (A1)
  113. @patch:
  114.         CMPI.W        #0x0609,D0
  115.         BEQ            @moveDisplay
  116. @hack1:
  117.         JMP            'hack'
  118. @moveDisplay:
  119.         MOVE.L        (SP),-(SP)                // dup return address; make room for...
  120. @hack2:
  121.         MOVE.L        #'hack',4(SP)            // ...old DisplayDispatch address
  122.         JMP            MoveDisplayPatch        // 'call'
  123.         RTS                                    // make disassembler happy
  124. }
  125.  
  126. extern void __Startup__ (void);
  127.  
  128. pascal void main (void)
  129. {
  130.     long preservedA4 = SetCurrentA4 ( );
  131.  
  132.     struct { QDGlobals qd; QDGlobalsPtr qdp; } qdGlobals;
  133.     long preservedA5 = SetA5 (long (&(qdGlobals.qdp)));
  134.     InitGraf (&(qdGlobals.qd.thePort));
  135.  
  136.     if (GDHandle mainDevice = ::GetMainDevice ( ))
  137.     {
  138.         gStripDevice = ::NewGDevice ((**mainDevice).gdRefNum, (**mainDevice).gdMode);
  139.  
  140.         if (gStripDevice)
  141.         {
  142.             AdjustStripDevice ( );
  143.  
  144.             (**gStripDevice).gdNextGD = (**mainDevice).gdNextGD;
  145.             (**mainDevice).gdNextGD = Handle (gStripDevice);
  146.  
  147.             ::DetachResource (::Get1Resource ('INIT',0));
  148. //            ::DetachResource (::RecoverHandle (Ptr (__Startup__)));
  149.  
  150.             UniversalProcPtr upp = ::GetToolTrapAddress (_DisplayDispatch);
  151.             upp = ::DisplayDispatchPatchAsm (upp);
  152.             ::SetToolTrapAddress (upp,_DisplayDispatch);
  153.  
  154.             gInitGDevice = vInitGDevice (::GetToolTrapAddress (_InitGDevice));
  155.             ::SetToolTrapAddress (UniversalProcPtr (InitGDevicePatch), _InitGDevice);
  156.         }
  157.     }
  158.  
  159.     (void) SetA5 (preservedA5);
  160.     (void) SetA4 (preservedA4);
  161. }
  162.